package com.usv.comparepic;

import static java.lang.Math.abs;

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import com.usv.drawer.DifferenceDrawer;
import com.usv.drawer.impl.DifferenceFileDrawer;

public class ComparePic {

    public static Color COLOR_DIFF = Color.red;
    public static int PERCENT_TOLERANCE = 10;
    private DifferenceDrawer diffDrawer = new DifferenceFileDrawer();

    public boolean compareTwoImages(BufferedImage bufImgOne, BufferedImage bufImgTwo) {

        List<Integer> listX = new ArrayList<>();
        List<Integer> listY = new ArrayList<>();

        int imgTwoWt = bufImgTwo.getWidth();
        int imgTwoHt = bufImgTwo.getHeight();

        if (isDifferentSize(bufImgOne, bufImgTwo)) {

            diffDrawer.drawDifference(bufImgTwo, 0, 0, imgTwoWt--, imgTwoHt--, COLOR_DIFF);
            return false;
        }

        for (int x = 0; x < imgTwoWt; x++) {
            for (int y = 0; y < imgTwoHt; y++) {
                if (isDifferentPixel(bufImgOne, bufImgTwo, x, y, PERCENT_TOLERANCE)) {

                    listX.add(x);
                    listY.add(y);
                }
            }
        }

        if (listX.isEmpty()) {

            System.out.println("Both of the pictures look the same.");
            return true;
        }
        findSelections(listX, listY, bufImgTwo);
        return true;
    }

    private static boolean isDifferentSize(BufferedImage bufImgOne, BufferedImage bufImgTwo) {

        int imgOneHt = bufImgOne.getHeight();
        int imgTwoHt = bufImgTwo.getHeight();
        int imgOneWt = bufImgOne.getWidth();
        int imgTwoWt = bufImgTwo.getWidth();
        return imgOneHt != imgTwoHt || imgOneWt != imgTwoWt;
    }

    private boolean isDifferentPixel(BufferedImage bufImgOne, BufferedImage bufImgTwo,
            int x, int y, int percent) {

        boolean result = false;
        int tolerance = 255 * percent / 100;

        int pixel1 = bufImgOne.getRGB(x, y);
        int pixel2 = bufImgTwo.getRGB(x, y);

        int alpha1 = (pixel1 >> 24) & 0xff;
        int red1 = (pixel1 >> 16) & 0xff;
        int green1 = (pixel1 >> 8) & 0xff;
        int blue1 = (pixel1 >> 0) & 0xff;

        int alpha2 = (pixel2 >> 24) & 0xff;
        int red2 = (pixel2 >> 16) & 0xff;
        int green2 = (pixel2 >> 8) & 0xff;
        int blue2 = (pixel2 >> 0) & 0xff;

        if (abs(alpha1 - alpha2) > tolerance || abs((red1 - red2)) > tolerance
                || abs(green1 - green2) > tolerance || abs(blue1 - blue2) > tolerance) {

            result = true;
        }
        return result;
    }

    private void findSelections(List<Integer> listX, List<Integer> listY, BufferedImage bufImgTwo) {
        // Находим левую границу     
        int x1 = Collections.min(listX);
        int startIndex = listX.indexOf(x1);
        int x2 = x1;
        int endIndex = startIndex;

        int y1 = 0;
        int y2 = 0;
System.out.println(x1);
//        while (startIndex < listX.size()-1) {
// Находим правую границу 

            while (listX.contains(x2)) {
                endIndex = listX.lastIndexOf(x2);
                x2++;
            }
System.out.println(x2);
            System.out.println("endIndex" + endIndex);
// Находим верхнюю границу

            y1 = Collections.min(listY.subList(startIndex, endIndex + 1));

// Находим нижнюю границу первого пятна

            while (listY.contains(y2)) {
                endIndex = listY.lastIndexOf(y2);
                y2++;
            }
        System.out.println(y2);
// Находим правую границу первого пятна
            while (listX.contains(x2)) {
                endIndex = listX.lastIndexOf(x2);
                x2++;
            }
        System.out.println(x2);    

//            x1 = Collections.min(listX.subList(startIndex, endIndex + 1));

            diffDrawer.drawDifference(bufImgTwo, x1, y1, x2, y2, COLOR_DIFF);

            startIndex = endIndex + 1;
        }
    }

